package com.ruoyi.project.download;

import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Implementation for {@link FileBytesCopier} which support skip specified bytes.
 *
 * @author zw
 */
@Component
public class DefaultFileBytesCopier implements FileBytesCopier {

  private static final int BUFFER_SIZE = 102400;

  @Override
  public void copyRange(OutputStream ostream, String path, Range range)
      throws IOException {
    Assert.hasText(path, "'path' must not be empty");
    copyRange(ostream, Paths.get(path), range);
  }

  @Override
  public void copyRange(OutputStream ostream, Path path, Range range)
      throws IOException {

    boolean isPartially = range.start > 0;
    try (InputStream in = Files.newInputStream(path)) {
      if (isPartially) {
        long skip = in.skip(range.start);
        if (skip < range.start) {
          throw new IOException(
              "Failed do skip for file " + path + ", expect skip " + range.start + " but skip "
                  + skip
          );
        }
      }

      long bytesToRead = range.end - range.start + 1;
      byte[] buffer = new byte[BUFFER_SIZE];
      int len;
      while (bytesToRead > 0) {
        len = in.read(buffer);
        if (bytesToRead >= len) {
          ostream.write(buffer, 0, len);
          bytesToRead -= len;
        } else {
          ostream.write(buffer, 0, (int) bytesToRead);
          bytesToRead = 0;
        }
      }
    }

  }

}
